//---------------------------------------------------------------------------

#include "vcl_stl.h"
#pragma hdrstop

#include "h_base.h"
#include "h_xml.h"
#include "h_global.h"
using namespace h_base;
using namespace h_xml;

#include "h_stage.h"
#include "h_designcontrol.h"
#include "t_mainform.h"
#include "t_aboutform.h"
#include "t_batform.h"
#include "h_g.h"
#include "h_server.h"
#include "h_portal.h"
#include "h_i18n.h"
#include "h_progressbar.h"

#include "t_selectskinform.h"
#include "t_confirmform.h"
#include "t_dummyform.h"
#include "t_listform.h"
#include "t_batlistform.h"
#include "t_cpathform.h"
#include "t_legendform.h"
#include "t_ganttform.h"
#include "t_concurrencyform.h"
#include "t_conditionform.h"
#include "t_downloadform.h"

#include "t_mainform.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMainForm *MainForm;
//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
   : TForm(Owner)
{
   Portal = NULL;
   Application->HintHidePause = 10000;
   NewGroup();
   MediaOpened = false;
   PanelAttention->Visible = false;
   NavIdx = 0;
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormShow(TObject *Sender)
{
   static bool First = true;

   if ( First )
   {
      HLogoIcon *Icon = new HLogoIcon(this);
      Icon->Left = 0;
      Icon->Top = 0;
      Icon->Align = alClient;
      Icon->Parent = Panel2;
      if( h_g::InitFail )
      {
         Close();
         return;
      }
   }
}
//---------------------------------------------------------------------------


void __fastcall TMainForm::FileExitExecute(TObject *Sender)
{
   Close();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::HelpAboutExecute(TObject *Sender)
{
   AboutForm->ShowModal();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FormDestroy(TObject *Sender)
{
   h_g::Close();
   HComm::Close();
}
//---------------------------------------------------------------------------



void __fastcall TMainForm::FileRefreshExecute(TObject *Sender)
{
   Refresh();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::ActionList1Update(TBasicAction *Action,
      bool &Handled)
{
   AnalyzeCalcCriticalPath->Enabled = false;
   AnalyzeDrawGanttChart->Enabled = false;
   AnalyzeDrawConcurrencyChart->Enabled = false;
   AnalyzeViewSummary->Enabled = false;

   BatchDownload->Enabled = false;
   BatchLoadStatus->Enabled = false;
   BatchGotoThis->Enabled = false;
   BatchPause->Enabled = false;
   BatchProperties->Enabled = false;
   BatchResume->Enabled = false;
   BatchSaveStatus->Enabled = false;
   BatchStart->Enabled = false;
   BatchStop->Enabled = false;

   FileBackward->Enabled = NavIdx > 0;
   FileForward->Enabled = NavIdx + 1 < NavVec.size();

   HBatchIcon *Batch = Portal->CurrentBatch;

   if ( Batch == NULL )
   {
      FileHome->Enabled = false;
      FileUp->Enabled = false;
      return;
   }

   BatchProperties->Enabled = true;
   FileHome->Enabled = Batch->Entered && PageControl1->ActivePageIndex != 0;
   FileList->Enabled = true;
   FileUp->Enabled = Batch->Entered;
   AnalyzeDrawGanttChart->Enabled = Batch->Entered;
   AnalyzeDrawConcurrencyChart->Enabled = Batch->Entered;
   AnalyzeCalcCriticalPath->Enabled = Batch->Entered;
   Batch->Lock();
   h_g::HIconType Status = Batch->OutlineStatus.Status;
   Batch->Unlock();

   if ( Batch->Outline.Offline )
   {
      if ( !Batch->Entered )
      {
         BatchLoadStatus->Enabled = true;
      }
      return;
   }

   if ( Status == h_g::itUnknown )
   {
      return;
   }

   AnalyzeViewSummary->Enabled = true;
   BatchDownload->Enabled = true;

   if ( !Batch->Entered )
   {
      BatchSaveStatus->Enabled = true;
      BatchGotoThis->Enabled = true;
   }

   switch ( Status )
   {
   case h_g::itNormal :
   case h_g::itSuccess :
      BatchStart->Enabled = ( Batch->Outline.Name != "" );
      if ( Status == h_g::itSuccess )
      {
         BatchResume->Enabled = true;
      }
      break;
   case h_g::itRunning :
   case h_g::itFailed :
   case h_g::itWaiting :
      BatchPause->Enabled = true;
      BatchStop->Enabled = true;
      break;
   case h_g::itPaused :
      BatchResume->Enabled = true;
      BatchStop->Enabled = true;
      break;
   default :
      break;
   }
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::BatchStartExecute(TObject *Sender)
{
   UTF8String TmpStr;
   HBatchIcon *Batch = Portal->CurrentBatch;

   if ( Batch->Outline.StartWindow != "" )
   {
      const char *StartWindow = Batch->Outline.StartWindow.c_str();
      int StartHour = 0;
      int StartMin = 0;
      int EndHour = 0;
      int EndMin = 0;
      bool ExitFlag = false;
      int Pos = 0;
      char w[80 + 1];
      if ( !ExitFlag )
      {
         Pos += ReadWord(StartWindow + Pos, w, " :,", 80);
         if ( ( isdigit(w[0]) && w[1] == '\0' ) ||
              ( isdigit(w[0]) && isdigit(w[1]) && w[2] == '\0' ) )
         {
            StartHour = StrToInt(w);
            if ( StartHour < 0 || StartHour > 23 )
            {
               ExitFlag = true;
            }
         }
         else
         {
            ExitFlag = true;
         }
      }
      if ( !ExitFlag )
      {
         Pos += ReadWord(StartWindow + Pos, w, " :,", 80);
         if ( strcmp(w, ":") != 0 )
         {
            ExitFlag = true;
         }
      }
      if ( !ExitFlag )
      {
         Pos += ReadWord(StartWindow + Pos, w, " :,", 80);
         if ( ( isdigit(w[0]) && w[1] == '\0' ) ||
              ( isdigit(w[0]) && isdigit(w[1]) && w[2] == '\0' ) )
         {
            StartMin = StrToInt(w);
            if ( StartMin < 0 || StartMin > 59 )
            {
               ExitFlag = true;
            }
         }
         else
         {
            ExitFlag = true;
         }
      }
      if ( !ExitFlag )
      {
         Pos += ReadWord(StartWindow + Pos, w, " :,", 80);
         if ( strcmp(w, ",") != 0 )
         {
            ExitFlag = true;
         }
      }
      if ( !ExitFlag )
      {
         Pos += ReadWord(StartWindow + Pos, w, " :,", 80);
         if ( ( isdigit(w[0]) && w[1] == '\0' ) ||
              ( isdigit(w[0]) && isdigit(w[1]) && w[2] == '\0' ) )
         {
            EndHour = StrToInt(w);
            if ( EndHour < 0 || EndHour > 23 )
            {
               ExitFlag = true;
            }
         }
         else
         {
            ExitFlag = true;
         }
      }
      if ( !ExitFlag )
      {
         Pos += ReadWord(StartWindow + Pos, w, " :,", 80);
         if ( strcmp(w, ":") != 0 )
         {
            ExitFlag = true;
         }
      }
      if ( !ExitFlag )
      {
         Pos += ReadWord(StartWindow + Pos, w, " :,", 80);
         if ( ( isdigit(w[0]) && w[1] == '\0' ) ||
              ( isdigit(w[0]) && isdigit(w[1]) && w[2] == '\0' ) )
         {
            EndMin = StrToInt(w);
            if ( EndMin < 0 || EndMin > 59 )
            {
               ExitFlag = true;
            }
         }
         else
         {
            ExitFlag = true;
         }
      }
      TDateTime CurrentDateTime = TDateTime::CurrentDateTime();
      TDateTime StartTime = TDateTime::CurrentDate() +
         TDateTime(StartHour, StartMin, 0, 0);
      TDateTime EndTime = TDateTime::CurrentDate() +
         TDateTime(EndHour, EndMin, 0, 0);
      if ( EndHour < StartHour ||
           ( EndHour == StartHour && EndMin < StartMin ) )
      {
         EndTime += TDateTime(12, 0, 0, 0) + TDateTime(12, 0, 0, 0);
      }
      if ( !ExitFlag )
      {
         if ( CurrentDateTime >= StartTime &&
              CurrentDateTime <= EndTime )
         {
            ExitFlag = true;
         }
      }
      StartTime -= TDateTime(12, 0, 0, 0) + TDateTime(12, 0, 0, 0);
      EndTime -= TDateTime(12, 0, 0, 0) + TDateTime(12, 0, 0, 0);
      if ( !ExitFlag )
      {
         if ( CurrentDateTime >= StartTime &&
              CurrentDateTime <= EndTime )
         {
            ExitFlag = true;
         }
      }
      if ( !ExitFlag )
      {
         TmpStr.sprintf(h_g::I18nString("t_mainform:OUT_OF_WINDOW"),
            StartWindow);
         h_g::ShowMessage(TmpStr);
         return;
      }
   }

   if ( Batch->Outline.BatchInterval != "" )
   {
      Batch->Lock();
      HOutlineStatus OutlineStatus = Batch->OutlineStatus;
      Batch->Unlock();
      const char *BatchInterval = Batch->Outline.BatchInterval.c_str();
      if ( OutlineStatus.EndTime != "" )
      {
         int Hour;
         int Min;
         char TmpStr[200 + 1];
         memcpy(TmpStr, BatchInterval, 2);
         TmpStr[2] = '\0';
         Hour = StrToInt(TmpStr);
         memcpy(TmpStr, BatchInterval + 3, 2);
         TmpStr[2] = '\0';
         Min = StrToInt(TmpStr);
         TDateTime EndTime;
         ToDateTime(FormatDateTime(OutlineStatus.EndTime), EndTime);
         if ( DateTimeToSec(TDateTime::CurrentDateTime() - EndTime) < ( Hour * 60 + Min ) * 60 )
         {
            UTF8String TmpStr;
            TmpStr.sprintf(h_g::I18nString("t_mainform:BATCH_INTERVAL_TOO_SHORT"),
               BatchInterval);
            h_g::ShowMessage(TmpStr);
            return;
         }
      }
   }

   TmpStr.sprintf(h_g::I18nString("t_mainform:START_BATCH_OF"),
      Portal->CurrentBatch->Outline.Name.c_str(),
      Portal->CurrentBatch->Outline.Caption.c_str());

   UTF8String BatchDate;
   UTF8String NextBatchDate;
   UTF8String EndBatchDate;

   Batch->Lock();
   BatchDate = Batch->OutlineStatus.NextScheduleDate;
   Batch->Unlock();

   if ( !CurrentBatchShowBatchDate() )
   {
      BatchDate = "";
   }

   if ( CurrentBatchEnableRestart() && CurrentBatchShowBatchDate() )
   {
      if ( !ConfirmForm->ConfirmStartBatch(Portal->CurrentBatch, BatchDate,
              NextBatchDate, EndBatchDate, TmpStr, "start_batch") )
      {
         return;
      }
   }
   else
   {
      if ( !ConfirmForm->ConfirmStartBatch(Portal->CurrentBatch, BatchDate,
              TmpStr, "start_batch") )
      {
         return;
      }
   }

   if ( !HServer::FuncStartBatch(Portal->CurrentBatch,
           BatchDate, NextBatchDate, EndBatchDate, TmpStr) )
   {
      h_g::ShowMessage(TmpStr);
   }

   Portal->CurrentBatch->Refresh();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::BatchPauseExecute(TObject *Sender)
{
   UTF8String TmpStr;

   TmpStr.sprintf(h_g::I18nString("t_mainform:PAUSE_BATCH_OF"),
      Portal->CurrentBatch->Outline.Caption.c_str());

   if ( !ConfirmForm->Confirm(Portal->CurrentBatch, TmpStr, "pause_batch") )
   {
      return;
   }

   if ( HServer::FuncPauseBatch(Portal->CurrentBatch, TmpStr) )
   {
      h_g::ShowMessage(UTF8String(h_g::I18nString("t_mainform:PAUSE_BATCH_SUCCESSFULLY")));
      Portal->CurrentBatch->Refresh();
   }
   else
      h_g::ShowMessage(TmpStr);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::BatchStopExecute(TObject *Sender)
{
   UTF8String TmpStr;

   TmpStr.sprintf(h_g::I18nString("t_mainform:STOP_BATCH_OF"),
      Portal->CurrentBatch->Outline.Caption.c_str());

   if ( !ConfirmForm->Confirm(Portal->CurrentBatch, TmpStr, "stop_batch") )
   {
      return;
   }

   if ( !ConfirmForm->Confirm(Portal->CurrentBatch,
           h_g::I18nString("t_mainform:LAST_CHANCE_STOP_BATCH"), "stop_batch") )
   {
      return;
   }

   if ( HServer::FuncStopBatch(Portal->CurrentBatch, TmpStr) )
   {
      h_g::ShowMessage(UTF8String(h_g::I18nString("t_mainform:STOP_BATCH_SUCCESSFULLY")));
      Portal->CurrentBatch->Refresh();
   }
   else
      h_g::ShowMessage(TmpStr);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FileHomeExecute(TObject *Sender)
{
   FuncHome();
}
//---------------------------------------------------------------------------


void __fastcall TMainForm::AnalyzeViewSummaryExecute(TObject *Sender)
{
   HServer::FuncViewSummary(Portal->CurrentBatch);
}
//---------------------------------------------------------------------------



void __fastcall TMainForm::BatchResumeExecute(TObject *Sender)
{
   UTF8String TmpStr;

   TmpStr.sprintf(h_g::I18nString("t_mainform:CONTINUE_BATCH_OF"),
      Portal->CurrentBatch->Outline.Caption.c_str());

   if ( !ConfirmForm->Confirm(Portal->CurrentBatch, TmpStr, "resume_batch") )
   {
      return;
   }

   if ( HServer::FuncContinueBatch(Portal->CurrentBatch, TmpStr) )
   {
      h_g::ShowMessage(UTF8String(h_g::I18nString("t_mainform:CONTINUE_BATCH_SUCCESSFULLY")));
      Portal->CurrentBatch->Refresh();
   }
   else
      h_g::ShowMessage(TmpStr);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::LoadFromXmlTree(HXmlTree *XmlTree)
{
   vector<HXmlTree*> Nodes;
   bool XmlPropertyFlag = false;

   RemoveAll();

   {
      vector<string> Version;
      SplitString(XmlTree->GetValue("VERSION"), '.', Version);
      if ( Version.size() == 3 )
      {
         int Ver = StrToInt(Version[0].c_str()) * 256 + StrToInt(Version[1].c_str());
         XmlPropertyFlag = ( Ver >= 0x0204 );
      }
   }

   if ( XmlPropertyFlag )
   {
      FInfo.Author = XmlTree->GetProperty("AUTHOR").c_str();
      FInfo.JobTrigger = XmlTree->GetProperty("JOB_TRIGGER").c_str();
      FInfo.BatchTrigger = XmlTree->GetProperty("BATCH_TRIGGER").c_str();
      HString Value = XmlTree->GetProperty("AUTO_SKIP");
      FInfo.AutoSkip = Value == "Y" || Value == "true";
      FInfo.AutoRerun = XmlTree->GetProperty("AUTO_RERUN").c_str();
      FInfo.Description = XmlTree->GetValues("DESCRIPTION").c_str();
      FInfo.IncludeFiles = XmlTree->GetValues("INCLUDE_FILES").c_str();
      Value = XmlTree->GetProperty("CHECK");
      FInfo.CheckBeforeTransfer = Value == "Y" || Value == "true";
      FInfo.FadingPeriod = XmlTree->GetProperty("FADING_PERIOD").c_str();
      FInfo.SectionList = XmlTree->GetProperty("SECTION_LIST").c_str();
      FInfo.TrafficControl = XmlTree->GetProperty("TRAFFIC_CONTROL").c_str();
      FInfo.Banner = XmlTree->GetProperty("BANNER").c_str();
      FInfo.BannerPosition =
         StrToInt(XmlTree->GetProperty("BANNER_POSITION", "0").c_str());
      FInfo.BannerFontName =
         XmlTree->GetProperty("BANNER_FONT_NAME", "Arial").c_str();
      FInfo.BannerFontSize =
         StrToInt(XmlTree->GetProperty("BANNER_FONT_SIZE", "8").c_str());
      FInfo.BannerFontStyle =
         StrToInt(XmlTree->GetProperty("BANNER_FONT_STYLE", "0").c_str());
   }
   else
   {
      FInfo.Author = XmlTree->GetValue("AUTHOR").c_str();
      FInfo.JobTrigger = XmlTree->GetValue("JOB_TRIGGER").c_str();
      FInfo.BatchTrigger = XmlTree->GetValue("BATCH_TRIGGER").c_str();
      HString Value = XmlTree->GetValue("AUTO_SKIP");
      FInfo.AutoSkip = Value == "Y" || Value == "true";
      FInfo.AutoRerun = XmlTree->GetValue("AUTO_RERUN").c_str();
      FInfo.Description = XmlTree->GetValues("DESCRIPTION").c_str();
      FInfo.IncludeFiles = XmlTree->GetValues("INCLUDE_FILES").c_str();
      Value = XmlTree->GetValue("CHECK");
      FInfo.CheckBeforeTransfer = Value == "Y" || Value == "true";
      FInfo.FadingPeriod = XmlTree->GetValue("FADING_PERIOD").c_str();
      FInfo.SectionList = XmlTree->GetValue("SECTION_LIST").c_str();
      FInfo.Banner = XmlTree->GetValue("BANNER").c_str();
      FInfo.BannerPosition =
         StrToInt(XmlTree->GetValue("BANNER_POSITION", "0").c_str());
      FInfo.BannerFontName =
         XmlTree->GetValue("BANNER_FONT_NAME", "Arial").c_str();
      FInfo.BannerFontSize =
         StrToInt(XmlTree->GetValue("BANNER_FONT_SIZE", "8").c_str());
      FInfo.BannerFontStyle =
         StrToInt(XmlTree->GetValue("BANNER_FONT_STYLE", "0").c_str());
   }

   XmlTree->GetChildren("GROUP", Nodes);

   for( int i = 0; i < Nodes.size(); i++ )
   {
      UTF8String GroupId;
      if ( XmlPropertyFlag )
      {
         GroupId = Nodes[i]->GetPropertyUpper("NAME").c_str();
      }
      else
      {
         GroupId = Nodes[i]->GetValueUpper("NAME").c_str();
      }
      NewGroup(GroupId, Nodes[i], XmlPropertyFlag, false);
   }

   PageControl1->ActivePageIndex = 0;
}

void __fastcall TMainForm::RefreshFromXmlTree(HXmlTree *XmlTree)
{
   vector<HXmlTree*> Nodes;
   bool XmlPropertyFlag = false;

   {
      vector<string> Version;
      SplitString(XmlTree->GetValue("VERSION"), '.', Version);
      if ( Version.size() == 3 )
      {
         int Ver = StrToInt(Version[0].c_str()) * 256 + StrToInt(Version[1].c_str());
         XmlPropertyFlag = ( Ver >= 0x0204 );
      }
   }

   ErrorJobName = "";

   {
      UTF8String OldBanner = FInfo.Banner;
      if ( XmlPropertyFlag )
      {
         FInfo.Banner = XmlTree->GetProperty("BANNER").c_str();
      }
      else
      {
         FInfo.Banner = XmlTree->GetValue("BANNER").c_str();
      }
      if ( FInfo.Banner != OldBanner )
      {
         if ( Portal->CurrentBatch != NULL && Portal->CurrentBatch->Entered )
         {
            HDesignControl *DesignControl = CurrentDesignControl();
            if ( DesignControl != NULL )
            {
               DesignControl->Invalidate();
            }
         }
      }
   }

   XmlTree->GetChildren("GROUP", Nodes);

   map<UTF8String, HXmlTree*> TmpGroupMap;

   for( int i = 0; i < Nodes.size(); i++ )
   {
      UTF8String Name;
      if ( XmlPropertyFlag )
      {
         Name = Nodes[i]->GetProperty("NAME").c_str();
      }
      else
      {
         Name = Nodes[i]->GetValue("NAME").c_str();
      }
      TmpGroupMap[Name] = Nodes[i];
   }

   for( int i = 0; i < Groups.size(); i++ )
   {
      UTF8String Name = Groups[i].TabSheet->Caption;
      if ( TmpGroupMap.find(Name) != TmpGroupMap.end() )
      {
         Groups[i].DesignControl->RefreshFromXmlTree(TmpGroupMap[Name],
            XmlPropertyFlag, ErrorJobName);
      }
   }
}

void __fastcall TMainForm::RemoveAll(void)
{
   for( int i = 0; i < Groups.size(); i++ )
      delete Groups[i].TabSheet;

   Groups.clear();
   GroupMap.clear();
}

void __fastcall TMainForm::NewGroup(const UTF8String &Name,
   HXmlTree* Node, bool XmlPropertyFlag, bool MakePageActive)
{
   int i;
   HGroupInfo GroupInfo;

   GroupInfo.TabSheet = new TTabSheet(this);

   if( Name == "" || GroupExist(Name) )
   {
      for( i = 1; GroupExist(UTF8String("Group") + UTF8String(i)) ; i++ )
         ;
      GroupInfo.TabSheet->Caption = UTF8String("Group") + UTF8String(i);
   }
   else
      GroupInfo.TabSheet->Caption = Name;

   GroupInfo.TabSheet->PageControl = PageControl1;
   GroupInfo.DesignControl = new HDesignControl(GroupInfo.TabSheet);
   GroupInfo.DesignControl->Align = alClient;
   GroupInfo.DesignControl->Parent = GroupInfo.TabSheet;
   GroupInfo.DesignControl->PopupMenu = PopupMenu1;
   Groups.push_back(GroupInfo);
   GroupMap[Name] = Groups.size() - 1;

   if ( Node != NULL )
   {
      GroupInfo.DesignControl->LoadFromXmlTree(Name, Node, XmlPropertyFlag);
   }

   if ( MakePageActive )
   {
      PageControl1->ActivePageIndex = Groups.size() - 1;
   }
}

bool __fastcall TMainForm::GroupExist(const UTF8String &Name)
{
   for( int i = 0; i < Groups.size(); i++ )
      if( Groups[i].TabSheet->Caption == Name )
         return true;

   return false;
}

HDesignControl * __fastcall TMainForm::CurrentDesignControl(void)
{
   int Index = PageControl1->ActivePageIndex;

   if( Index == -1 )
      return NULL;
   else
      return Groups[Index].DesignControl;
}

bool __fastcall TMainForm::GotoPage(const UTF8String &Group,
   int HScrollPosition, int VScrollPosition)
{
   if ( GroupMap.find(Group) == GroupMap.end() )
   {
      return false;
   }

   GotoPage(GroupMap[Group]);

   {
      int Idx = PageControl1->ActivePageIndex;
      Groups[Idx].DesignControl->HorzScrollBar->Position = HScrollPosition;
      Groups[Idx].DesignControl->VertScrollBar->Position = VScrollPosition;
   }

   return true;
}

void __fastcall TMainForm::GotoPage(int Index)
{
   PageControl1->ActivePageIndex = Index;
}

void __fastcall TMainForm::HMRefreshComplete(TMessage &Message)
{
   HServer::RefreshComplete((HBatchIcon*)Message.WParam);
}

void __fastcall TMainForm::HMEnterBatch(TMessage &Message)
{
   Portal->SetCurrentBatch((HBatchIcon*)Message.WParam);
   BatchGotoThisExecute(NULL);
}

void __fastcall TMainForm::HMProgress(TMessage &Message)
{
   if ( Message.LParam == 1 )
   {
      ProgressBar->ShowFlag = false;
      return;
   }

   if ( Portal->CurrentBatch != NULL &&
        Portal->CurrentBatch->Entered )
   {
      ProgressBar->Rate = Message.WParam;
      ProgressBar->ShowFlag = true;
   }
}

void __fastcall TMainForm::RefreshBatchColor(int ServerIdx)
{
   if ( Portal->CurrentBatch == NULL || !Portal->CurrentBatch->Entered )
   {
      return;
   }

   for ( int i = 0; i < Groups.size(); i++ )
   {
      HGroupInfo &Group = Groups[i];
      Group.DesignControl->RefreshBatchColor(ServerIdx);
   }
}

void __fastcall TMainForm::RefreshCaption(void)
{
   Invalidate();

   if ( Portal->CurrentBatch != NULL && Portal->CurrentBatch->Entered )
   {
      for ( int i = 0; i < Groups.size(); i++ )
      {
         Groups[i].DesignControl->RefreshCaption();
      }
      HDesignControl *DesignControl = CurrentDesignControl();
      if ( DesignControl != NULL )
      {
         DesignControl->Invalidate();
      }
   }
   else
   {
      Portal->RefreshCaption();
   }
}

void __fastcall TMainForm::Refresh(void)
{
   HServer::UnlockRefresh();
   Portal->Refresh();
}

void __fastcall TMainForm::GetInfo(HInfo &Info)
{
   FInfo.GroupName = PageControl1->ActivePage->Caption;
   Info = FInfo;
}

void __fastcall TMainForm::FuncHome(void)
{
   TruncNavInfo();
   SaveNavInfo();
   GotoPage(0);
   NavIdx++;
}

bool __fastcall TMainForm::CanHome(void)
{
   return Portal->CurrentBatch != NULL && Portal->CurrentBatch->Entered;
}

void __fastcall TMainForm::FuncUp(void)
{
   int Idx = PageControl1->ActivePageIndex;

   if ( Idx == -1 )
   {
      Portal->CurrentBatch->Entered = false;
      PageControl1->Visible = false;
      Portal->Visible = true;
      ProgressBar->ShowFlag = false;
      MainForm->Caption = h_g::MainformCaption;
      NavVec.clear();
      NavIdx = 0;
      return;
   }

   UTF8String ThisGroupName = Groups[Idx].TabSheet->Caption;

   int i;

   for ( i = 0; i < Groups.size(); i++ )
   {
      if ( Groups[i].DesignControl->GroupExist(ThisGroupName) )
      {
         break;
      }
   }

   if ( i == Groups.size() )
   {
      Portal->CurrentBatch->Entered = false;
      PageControl1->Visible = false;
      Portal->Visible = true;
      MainForm->Caption = h_g::MainformCaption;
      NavVec.clear();
      NavIdx = 0;
   }
   else
   {
      TruncNavInfo();
      SaveNavInfo();
      NavIdx++;
      PageControl1->ActivePageIndex = i;
   }
}

bool __fastcall TMainForm::CurrentBatchIsRunning()
{
   HBatchIcon *Batch = Portal->CurrentBatch;
   Batch->Lock();
   h_g::HIconType Status = Batch->OutlineStatus.Status;
   Batch->Unlock();

   return ( Status == h_g::itRunning || Status == h_g::itFailed ||
      Status == h_g::itWaiting || Status == h_g::itPaused );
}

bool __fastcall TMainForm::CurrentBatchIsCompleted()
{
   HBatchIcon *Batch = Portal->CurrentBatch;
   Batch->Lock();
   h_g::HIconType Status = Batch->OutlineStatus.Status;
   Batch->Unlock();

   return Status == h_g::itSuccess;
}

bool __fastcall TMainForm::CurrentBatchEnableRestart()
{
   HBatchIcon *Batch = Portal->CurrentBatch;

   return Batch->Outline.EnableRestart;
}

bool __fastcall TMainForm::CurrentBatchShowBatchDate()
{
   HBatchIcon *Batch = Portal->CurrentBatch;

   return Batch->Outline.ShowBatchDate;
}

void __fastcall TMainForm::PopupMenu1Popup(TObject *Sender)
{
   UTF8String Type = SelectedStage->GetType();

   GoToThisGroup1->Enabled = ( Type == "GROUP" || Type == "EXTERN_JOB" ||
      Type == "BATCH" );

   HBatchIcon *Batch = Portal->CurrentBatch;

   if ( Batch->Outline.Offline )
   {
      Skip1->Enabled = false;
      Restore1->Enabled = false;
      Rerun1->Enabled = false;
      Restart1->Enabled = false;
      Stop1->Enabled = false;
      ChangeCondition1->Enabled = false;
      StopAndSkip1->Enabled = false;
      ViewLog1->Enabled = false;
      FireThisEvent1->Enabled = false;
      ViewAdditionalLog1->Enabled = false;
      ViewRestoreLog1->Enabled = false;
      Breakpoint1->Enabled = false;
      return;
   }

   Skip1->Enabled = CurrentBatchIsRunning() &&
      SelectedStage->CanSkip();

   Restore1->Enabled = CurrentBatchIsRunning() &&
      SelectedStage->CanRestore();

   Rerun1->Enabled = CurrentBatchIsRunning() &&
      SelectedStage->CanRerun();

   Restart1->Enabled = CurrentBatchEnableRestart() &&
      ( CurrentBatchIsRunning() || CurrentBatchIsCompleted() ) &&
      SelectedStage->CanRestart();

   Stop1->Enabled = CurrentBatchIsRunning() &&
      SelectedStage->CanStop();

   ChangeCondition1->Enabled = ( CurrentBatchIsRunning() || CurrentBatchIsCompleted() ) &&
      SelectedStage->CanChangeCondition();

   StopAndSkip1->Enabled = CurrentBatchIsRunning() &&
      SelectedStage->CanStop();

   ViewLog1->Enabled = SelectedStage->CanViewLog();
   FireThisEvent1->Enabled = SelectedStage->GetEventName() != "";
   ViewAdditionalLog1->Enabled = SelectedStage->CanViewAdditionalLog();
   ViewRestoreLog1->Enabled = SelectedStage->CanViewRestoreLog();

   Breakpoint1->Enabled = CurrentBatchIsRunning() &&
      SelectedStage->CanBreakpoint();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::Skip(const UTF8String &JobName)
{
   UTF8String TmpStr;

   TmpStr.sprintf(h_g::I18nString("t_mainform:SKIP_JOB"),
      JobName.c_str());

   UTF8String ErrorString;

   if ( !ConfirmForm->Confirm(Portal->CurrentBatch, TmpStr, "skip_job") )
   {
      return;
   }

   if( HServer::FuncSkipJob(Portal->CurrentBatch, JobName, ErrorString) )
   {
      Sleep(200);
      Portal->Refresh();
   }
   else
      h_g::ShowMessage(ErrorString);
}

void __fastcall TMainForm::Skip1Click(TObject *Sender)
{
   UTF8String JobName = SelectedStage->GetGroupId() + h_g::JobNameDelimiter +
      SelectedStage->GetName();

   Skip(JobName);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::Restore(const UTF8String &JobName)
{
   UTF8String TmpStr;

   TmpStr.sprintf(h_g::I18nString("t_mainform:RESTORE_JOB"),
      JobName.c_str());

   UTF8String ErrorString;

   if ( !ConfirmForm->Confirm(Portal->CurrentBatch, TmpStr, "restore_job") )
   {
      return;
   }

   if( HServer::FuncRestoreJob(Portal->CurrentBatch, JobName, ErrorString) )
   {
      Sleep(200);
      Portal->Refresh();
   }
   else
      h_g::ShowMessage(ErrorString);
}

void __fastcall TMainForm::Restore1Click(TObject *Sender)
{
   UTF8String JobName = SelectedStage->GetGroupId() + h_g::JobNameDelimiter +
      SelectedStage->GetName();

   Restore(JobName);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::Rerun(const UTF8String &JobName)
{
   UTF8String TmpStr;

   TmpStr.sprintf(h_g::I18nString("t_mainform:RERUN_JOB"),
      JobName == "" ? "ALL" : JobName.c_str());

   UTF8String ErrorString;

   if ( !ConfirmForm->Confirm(Portal->CurrentBatch, TmpStr, "rerun_job") )
   {
      return;
   }

   if( HServer::FuncRerunJob(Portal->CurrentBatch, JobName, ErrorString) )
   {
      Sleep(200);
      Portal->Refresh();
   }
   else
      h_g::ShowMessage(ErrorString);
}

void __fastcall TMainForm::Rerun1Click(TObject *Sender)
{
   UTF8String JobName = SelectedStage->GetGroupId() + h_g::JobNameDelimiter +
      SelectedStage->GetName();

   Rerun(JobName);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::Stop(const UTF8String &JobName)
{
   UTF8String TmpStr;

   TmpStr.sprintf(h_g::I18nString("t_mainform:STOP_JOB"),
      JobName.c_str());

   UTF8String ErrorString;

   if ( !ConfirmForm->Confirm(Portal->CurrentBatch, TmpStr, "stop_job") )
   {
      return;
   }

   if( HServer::FuncStopJob(Portal->CurrentBatch, JobName, ErrorString) )
   {
      Sleep(200);
      Portal->Refresh();
   }
   else
      h_g::ShowMessage(ErrorString);
}

void __fastcall TMainForm::Stop1Click(TObject *Sender)
{
   UTF8String JobName = SelectedStage->GetGroupId() + h_g::JobNameDelimiter +
      SelectedStage->GetName();

   Stop(JobName);
}
//---------------------------------------------------------------------------


void __fastcall TMainForm::ViewLog(const UTF8String &JobName)
{
   HStage *Stage = FindControlByName(JobName);

   if ( Stage == NULL )
   {
      return;
   }

   if ( Stage->GetPartFlag() )
   {
      HServer::LockRefresh();
      Stage->EditProperty(true);
      HServer::UnlockRefresh();
   }
   else
   {
      HServer::FuncViewLog(Portal->CurrentBatch, JobName);
   }
}

void __fastcall TMainForm::ViewLog1Click(TObject *Sender)
{
   UTF8String JobName = SelectedStage->GetGroupId() + h_g::JobNameDelimiter +
      SelectedStage->GetName();

   ViewLog(JobName);
}
//---------------------------------------------------------------------------


void __fastcall TMainForm::FileChangeSkinExecute(TObject *Sender)
{
   UTF8String Skin = SelectSkinForm->Select();

   if ( Skin != "" )
   {
      h_g::ChangeSkin(Skin);
   }
}
//---------------------------------------------------------------------------


void __fastcall TMainForm::ViewAdditionalLog1Click(TObject *Sender)
{
   UTF8String JobName = SelectedStage->GetGroupId() + h_g::JobNameDelimiter +
      SelectedStage->GetName();
   HStage *Stage = FindControlByName(JobName);

   if ( Stage == NULL )
   {
      return;
   }

   if ( Stage->GetPartFlag() )
   {
      HServer::FuncViewLog(Portal->CurrentBatch, JobName);
   }
   else
   {
      HServer::FuncViewAdditionalLog(Portal->CurrentBatch, JobName);
   }
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::AnalyzeCalcCriticalPathExecute(TObject *Sender)
{
#ifdef SIMBAT_ENTERPRISE
   CpathForm->ShowIt();
#else
   h_g::ShowMessage(UTF8String(h_g::I18nString("h_g:ENTERPRISE_ONLY")));
#endif
}
//---------------------------------------------------------------------------


void __fastcall TMainForm::FireThisEvent1Click(TObject *Sender)
{
   UTF8String ErrorString;
   UTF8String EventName = SelectedStage->GetEventName();
   UTF8String TmpStr;

   TmpStr.sprintf(h_g::I18nString("t_mainform:FIRE_EVENT"),
      EventName.c_str());

   if ( !ConfirmForm->Confirm(Portal->CurrentBatch, TmpStr, "fire_event") )
   {
      return;
   }

   if( !HServer::FuncFireEvent(Portal->CurrentBatch, EventName, ErrorString) )
      h_g::ShowMessage(ErrorString);
}
//---------------------------------------------------------------------------


void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action)
{
   h_g::ExitFlag = true;

   if ( Portal != NULL )
   {
      Portal->Close();
   }
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::EnterBatch(const UTF8String &StatusFileName)
{
   TruncNavInfo();
   SaveNavInfo();
   NavIdx++;

   HBatchIcon *Batch = Portal->CurrentBatch;

   RemoveAll();
   Portal->Visible = false;
   PageControl1->Visible = true;
   Batch->Lock();
   Batch->StatusFileName = StatusFileName;
   Batch->Unlock();
   Batch->Entered = true;
   strcpy(h_g::JobNameDelimiter, Batch->Outline.JobNameDelimiter.c_str());
   MainForm->Caption = Batch->Outline.Caption;
}

void __fastcall TMainForm::BatchGotoThisExecute(TObject *Sender)
{
   EnterBatch("");
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::BatchPropertiesExecute(TObject *Sender)
{
   Portal->ShowBatchProperties();
}
//---------------------------------------------------------------------------



void __fastcall TMainForm::Restart(const UTF8String &JobName)
{
   UTF8String TmpStr;

   TmpStr.sprintf(h_g::I18nString("t_mainform:RESTART_JOB"),
      JobName.c_str());

   UTF8String ErrorString;
   UTF8String BatchDate;
   UTF8String NextBatchDate;

   if ( !CurrentBatchShowBatchDate() )
   {
      BatchDate = "";
   }

   if ( CurrentBatchEnableRestart() )
   {
      if ( !ConfirmForm->ConfirmRestartJob(Portal->CurrentBatch,
              BatchDate, NextBatchDate, TmpStr, "restart_job") )
      {
         return;
      }
   }
   else
   {
      if ( !ConfirmForm->Confirm(Portal->CurrentBatch, TmpStr, "restart_job") )
      {
         return;
      }
   }

   if( HServer::FuncRestartJob(Portal->CurrentBatch, JobName, BatchDate, NextBatchDate, ErrorString) )
   {
      Sleep(200);
      Portal->Refresh();
   }
   else
      h_g::ShowMessage(ErrorString);
}

void __fastcall TMainForm::Restart1Click(TObject *Sender)
{
   UTF8String JobName = SelectedStage->GetGroupId() + h_g::JobNameDelimiter +
      SelectedStage->GetName();

   Restart(JobName);
}
//---------------------------------------------------------------------------


void __fastcall TMainForm::FileUpExecute(TObject *Sender)
{
   FuncUp();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FileListExecute(TObject *Sender)
{
   if ( Portal->CurrentBatch == NULL || !Portal->CurrentBatch->Entered )
   {
      BatListForm->ShowModal();
   }
   else
   {
      ListForm->ShowModal();
   }
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::SaveToJobList(map<UTF8String, HJobListInfo> &JobMap,
   bool CriticalFlag)
{
   for ( int i = 0; i < Groups.size(); i++ )
   {
      Groups[i].DesignControl->SaveToJobList(JobMap, CriticalFlag);
   }
}

void __fastcall TMainForm::SaveToBatList(map<int, HBatListInfo> &BatMap)
{
   Portal->SaveToBatList(BatMap);
}

void __fastcall TMainForm::SaveToPartTimeList(vector<HPartTimeInfo> &PartVec)
{
   PartVec.clear();

   for ( int i = 0; i < Groups.size(); i++ )
   {
      Groups[i].DesignControl->SaveToPartTimeList(PartVec);
   }
}

void __fastcall TMainForm::SaveToGanttList(const TDateTime &StartTime,
   const TDateTime &EndTime, bool PartitionFlag, int Time, vector<HGanttInfo> &Vec)
{
   Vec.clear();

   for ( int i = 0; i < Groups.size(); i++ )
   {
      Groups[i].DesignControl->SaveToGanttList(StartTime, EndTime, PartitionFlag, Time, Vec);
   }
}

HStage * __fastcall TMainForm::FindControlByName(const UTF8String &Name)
{
   vector<string> StrVec;

   SplitString(Name.c_str(), *h_g::JobNameDelimiter, StrVec, true);

   if ( StrVec.size() != 2 )
   {
      return NULL;
   }

   UTF8String GroupName = StrVec[0].c_str();
   UTF8String JobName = StrVec[1].c_str();

   if ( GroupMap.find(GroupName) == GroupMap.end() )
   {
      return NULL;
   }

   return Groups[GroupMap[GroupName]].DesignControl->FindControlByName(JobName);
}

bool __fastcall TMainForm::GotoGroupAndFocusToJob(const UTF8String &Name)
{
   vector<string> StrVec;

   SplitString(Name.c_str(), *h_g::JobNameDelimiter, StrVec, true);

   if ( StrVec.size() != 1 && StrVec.size() != 2 )
   {
      return false;
   }

   if ( StrVec.size() == 1 )
   {
      StrVec.push_back("");
   }

   UTF8String GroupName = StrVec[0].c_str();
   UTF8String JobName = StrVec[1].c_str();

   if ( GroupMap.find(GroupName) == GroupMap.end() )
   {
      return false;
   }

   TruncNavInfo();
   SaveNavInfo();
   NavIdx++;
   GotoPage(GroupName);
   Groups[GroupMap[GroupName]].DesignControl->SetFocusedJob(JobName, true);
   return true;
}


void __fastcall TMainForm::BatchDownloadExecute(TObject *Sender)
{
   UTF8String SrcFileName;
   UTF8String DesFileName;

   if ( !DownloadForm->GetFileName(SrcFileName, DesFileName) )
   {
      return;
   }

   HServer::FuncDownload(Portal->CurrentBatch, SrcFileName, DesFileName);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::HelpLegendExecute(TObject *Sender)
{
   LegendForm->ShowModal();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::AnalyzeDrawGanttChartExecute(TObject *Sender)
{
#ifdef SIMBAT_ENTERPRISE
   GanttForm->ShowIt();
#else
   h_g::ShowMessage(UTF8String(h_g::I18nString("h_g:ENTERPRISE_ONLY")));
#endif
}
//---------------------------------------------------------------------------


void __fastcall TMainForm::ChangeCondition1Click(TObject *Sender)
{
   UTF8String JobName = SelectedStage->GetGroupId() + h_g::JobNameDelimiter +
      SelectedStage->GetName();

   ChangeCondition(JobName);
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::ChangeCondition(const UTF8String &JobName)
{
   bool CondNot;
   UTF8String ConditionFile;
   UTF8String SpecialDate;
   UTF8String LoopStartTime;
   UTF8String LoopEndTime;

   SelectedStage->GetJobCondition(CondNot, ConditionFile, SpecialDate, LoopStartTime, LoopEndTime);

   UTF8String ErrorString;

   if ( !ConditionForm->ChangeCondition(Portal->CurrentBatch, JobName, CondNot, ConditionFile,
           SpecialDate, LoopStartTime, LoopEndTime, "change_job_condition") )
   {
      return;
   }

   if( HServer::FuncChangeJobCondition(Portal->CurrentBatch,
          JobName, CondNot, ConditionFile, SpecialDate, LoopStartTime, LoopEndTime, ErrorString) )
   {
      Sleep(200);
      SelectedStage->SetJobCondition(CondNot, ConditionFile, SpecialDate, LoopStartTime, LoopEndTime);
      h_g::ShowMessage(UTF8String(h_g::I18nString("t_batchform:SUCCESS")));
      Portal->Refresh();
   }
   else
      h_g::ShowMessage(ErrorString);
}

void __fastcall TMainForm::StopAndSkip1Click(TObject *Sender)
{
   UTF8String JobName = SelectedStage->GetGroupId() + h_g::JobNameDelimiter +
      SelectedStage->GetName();

   StopAndSkip(JobName);
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::StopAndSkip(const UTF8String &JobName)
{
   UTF8String TmpStr;

   TmpStr.sprintf(h_g::I18nString("t_mainform:STOP_AND_SKIP_JOB"),
      JobName.c_str());

   UTF8String ErrorString;

   if ( !ConfirmForm->Confirm(Portal->CurrentBatch, TmpStr, "stop_job") )
   {
      return;
   }

   if( HServer::FuncStopAndSkipJob(Portal->CurrentBatch, JobName, ErrorString) )
   {
      Sleep(200);
      Portal->Refresh();
   }
   else
      h_g::ShowMessage(ErrorString);
}


void __fastcall TMainForm::BatchSaveStatusExecute(TObject *Sender)
{
   SaveDialog1->DefaultExt = "xml";
   SaveDialog1->FileName = Portal->CurrentBatch->Outline.Name;
   SaveDialog1->Filter =
      "XML files (*.xml)|*.xml|All files (*.*)|*.*";
   SaveDialog1->FilterIndex = 1;

   if ( SaveDialog1->InitialDir == "" )
   {
      SaveDialog1->InitialDir = h_g::BaseDir + "bats";
   }

   SaveDialog1->Options = TOpenOptions() << ofOverwritePrompt
      << ofEnableSizing;
   SaveDialog1->Title = UTF8String(h_g::I18nString("t_mainform:SAVE_STATUS_FILE_AS"));

   if( !SaveDialog1->Execute() )
   {
      return;
   }

   EnterBatch(SaveDialog1->FileName);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::BatchLoadStatusExecute(TObject *Sender)
{
   OpenDialog1->DefaultExt = "xml";
   OpenDialog1->FileName = "";
   OpenDialog1->Filter =
      "XML files (*.xml)|*.xml|All files (*.*)|*.*";
   OpenDialog1->FilterIndex = 1;

   if ( OpenDialog1->InitialDir == "" )
   {
      OpenDialog1->InitialDir = h_g::BaseDir + "bats";
   }

   OpenDialog1->Options = TOpenOptions() << ofPathMustExist
      << ofFileMustExist << ofEnableSizing;
   OpenDialog1->Title = UTF8String(h_g::I18nString("t_mainform:LOAD_STATUS_FILE"));

   if( !OpenDialog1->Execute() )
      return;

   EnterBatch(OpenDialog1->FileName);
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::Attention(const UTF8String &ACaption, bool Error)
{
   if ( PanelAttention->Visible || !h_g::AlarmEnableFlag )
   {
      return;
   }

   Label1->Caption = ACaption;
   PanelAttention->Top = ClientRect.Bottom - PanelAttention->Height - 10;
   PanelAttention->Left = 10;
   PanelAttention->Width = ClientRect.Width() - 20;
   PanelAttention->Color = (TColor)RGB(209, 186, 116);

   if( Error )
      OpenAttention(h_g::WhistleFile);
   else
      OpenAttention(h_g::EndSoundFile);

   PanelAttention->Visible = true;
   PanelAttention->BringToFront();
}
void __fastcall TMainForm::OpenAttention(const UTF8String &WhistleFile)
{
   if( WhistleFile == "" )
      return;

   MediaPlayer1->FileName = WhistleFile;
   MediaPlayer1->Open();
   MediaOpened = true;
   MediaPlayer1->Play();
}

void __fastcall TMainForm::MediaPlayer1Notify(TObject *Sender)
{
   if ( MediaOpened )
   {
      MediaPlayer1->Notify = true;
      Timer1->Enabled = true;
   }
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::CloseAttention()
{
   if ( MediaOpened )
   {
      MediaPlayer1->Close();
   }

   MediaOpened = false;
}

void __fastcall TMainForm::ButtonOkClick(TObject *Sender)
{
   CloseAttention();
   PanelAttention->Visible = false;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::Timer1Timer(TObject *Sender)
{
   Timer1->Enabled = false;

   if ( MediaOpened )
   {
      MediaPlayer1->Play();
   }
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::AnalyzeDrawConcurrencyChartExecute(
      TObject *Sender)
{
#ifdef SIMBAT_ENTERPRISE
   ConcurrencyForm->ShowIt();
#else
   h_g::ShowMessage(UTF8String(h_g::I18nString("h_g:ENTERPRISE_ONLY")));
#endif
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::ReloadUpperGroupMap()
{
   UpperGroupMap.clear();

   for( int i = 0; i < Groups.size(); i++ )
   {
      UTF8String Name = Groups[i].TabSheet->Caption;
      UpperGroupMap[Name] = "";
   }

   for( int i = 0; i < Groups.size(); i++ )
   {
      UTF8String Name = Groups[i].TabSheet->Caption;
      Groups[i].DesignControl->ReloadUpperGroupMap(Name, UpperGroupMap);
   }
}

void __fastcall TMainForm::ViewRestoreLog1Click(TObject *Sender)
{
   UTF8String JobName = SelectedStage->GetGroupId() + h_g::JobNameDelimiter +
      SelectedStage->GetName();
   HStage *Stage = FindControlByName(JobName);

   if ( Stage == NULL )
   {
      return;
   }

   HServer::FuncViewLog(Portal->CurrentBatch, JobName, true);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::GoToThisGroup1Click(TObject *Sender)
{
   HStageGroup *Group = dynamic_cast<HStageGroup*>(SelectedStage);

   if ( Group != NULL )
   {
      HStageGroup::HInfo Info;
      Group->GetInfo(Info);
      TruncNavInfo();
      SaveNavInfo();
      if ( GotoPage(Info.Group) )
      {
         NavIdx++;
      }
      return;
   }

   HStageExternJob *ExternJob = dynamic_cast<HStageExternJob*>(SelectedStage);

   if ( ExternJob != NULL )
   {
      HStageExternJob::HInfo Info;
      ExternJob->GetInfo(Info);
      GotoGroupAndFocusToJob(Info.ExternGroup +
         h_g::JobNameDelimiter + Info.ExternJob);
      return;
   }

   HStageBatch *BatchJob = dynamic_cast<HStageBatch*>(SelectedStage);

   if ( BatchJob != NULL )
   {
      HStageBatch::HInfo Info;
      BatchJob->GetInfo(Info);
      HBatchIcon *Batch = Info.BatchIcon;
      if ( Batch == Portal->CurrentBatch )
      {
         return;
      }
      TruncNavInfo();
      SaveNavInfo();
      NavIdx++;
      RemoveAll();
      if ( Portal->CurrentBatch != NULL )
      {
         Portal->CurrentBatch->Entered = false;
      }
      Portal->SetCurrentBatch(Batch);
      Batch->Entered = true;
      strcpy(h_g::JobNameDelimiter, Batch->Outline.JobNameDelimiter.c_str());
      MainForm->Caption = Batch->Outline.Caption;
   }
}
//---------------------------------------------------------------------------


void __fastcall TMainForm::Breakpoint1Click(TObject *Sender)
{
   HStageJob *Job = dynamic_cast<HStageJob*>(SelectedStage);

   if ( Job == NULL )
   {
      return;
   }

   UTF8String Status = Job->GetStatus();

   if ( Status != "WAITING" && Status != "FAIL" )
   {
      return;
   }

   UTF8String JobName = SelectedStage->GetGroupId() + h_g::JobNameDelimiter +
      SelectedStage->GetName();
   UTF8String TmpStr;

   TmpStr.sprintf(h_g::I18nString("t_mainform:BREAKPOINT"),
      JobName.c_str());

   UTF8String ErrorString;

   if ( !ConfirmForm->Confirm(Portal->CurrentBatch, TmpStr, "breakpoint") )
   {
      return;
   }

   if( HServer::FuncBreakpoint(Portal->CurrentBatch, JobName,
          Job->GetBreakpointFlag() ? "unset" : "set", ErrorString) )
   {
      Sleep(200);
      Portal->Refresh();
   }
   else
      h_g::ShowMessage(ErrorString);

}
//---------------------------------------------------------------------------

void __fastcall TMainForm::DoNav(const HNavInfo &Info)
{
   HBatchIcon *Batch = Portal->CurrentBatch;

   if ( Info.ServerIdx == -1 )
   {
      if ( Batch != NULL )
      {
         Batch->Entered = false;
      }
      PageControl1->Visible = false;
      Portal->Visible = true;
      Portal->HorzScrollBar->Position = Info.HScrollPosition;
      Portal->VertScrollBar->Position = Info.VScrollPosition;
   }
   else
   {
      if ( Batch == NULL || !Batch->Entered )
      {
         Portal->Visible = false;
         PageControl1->Visible = true;
         Portal->SetCurrentBatch(Info.ServerIdx);
         Batch = Portal->CurrentBatch;
         Batch->NavInfo = Info;
         Batch->Entered = true;
      }
      else
      {
         if ( Info.ServerIdx == Batch->Idx )
         {
            GotoPage(Info.GroupName, Info.HScrollPosition, Info.VScrollPosition);
         }
         else
         {
            RemoveAll();
            Batch->Entered = false;
            Portal->SetCurrentBatch(Info.ServerIdx);
            Batch = Portal->CurrentBatch;
            Batch->NavInfo = Info;
            Batch->Entered = true;
         }
      }
   }

   MainForm->Caption = Info.Caption;
   strcpy(h_g::JobNameDelimiter, Info.JobNameDelimiter);
}

void __fastcall TMainForm::FileBackwardExecute(TObject *Sender)
{
   SaveNavInfo();
   NavIdx--;

   HNavInfo &Info = NavVec[NavIdx];

   DoNav(Info);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FileForwardExecute(TObject *Sender)
{
   SaveNavInfo();
   NavIdx++;

   HNavInfo &Info = NavVec[NavIdx];

   DoNav(Info);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::SaveNavInfo()
{
   if ( NavVec.size() == NavIdx )
   {
      NavVec.push_back(HNavInfo());
   }

   HNavInfo &Info = NavVec[NavIdx];

   if ( Portal->CurrentBatch == NULL || !Portal->CurrentBatch->Entered )
   {
      Info.ServerIdx = -1;
      Info.Caption = MainForm->Caption;
      Info.GroupName = "";
      Info.HScrollPosition = Portal->HorzScrollBar->Position;
      Info.VScrollPosition = Portal->VertScrollBar->Position;
   }
   else
   {
      int Idx = PageControl1->ActivePageIndex;
      Info.ServerIdx = Portal->CurrentBatch->Idx;
      Info.Caption = MainForm->Caption;
      if ( Groups.empty() )
      {
         Info.GroupName = "";
         Info.HScrollPosition = 0;
         Info.VScrollPosition = 0;
      }
      else
      {
         Info.GroupName = Groups[Idx].TabSheet->Caption;
         Info.HScrollPosition = Groups[Idx].DesignControl->HorzScrollBar->Position;
         Info.VScrollPosition = Groups[Idx].DesignControl->VertScrollBar->Position;
      }
   }
}

void __fastcall TMainForm::TruncNavInfo()
{
   NavVec.resize(NavIdx);
}
void __fastcall TMainForm::BatchRerunAllExecute(TObject *Sender)
{
   Rerun("");
}
//---------------------------------------------------------------------------


